package com.superhelper.app.service;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URISyntaxException;
import java.net.URLEncoder;
import java.util.Calendar;
import java.util.List;
import java.util.Map;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.fasterxml.jackson.core.type.TypeReference;
import com.sankuai.sjst.platform.developer.domain.RequestSysParams;
import com.sankuai.sjst.platform.developer.request.CipCaterTakeoutOrderCancelRequest;
import com.sankuai.sjst.platform.developer.request.CipCaterTakeoutOrderConfirmRequest;
import com.sankuai.sjst.platform.developer.request.CipCaterTakeoutOrderQueryByIdRequest;
import com.sankuai.sjst.platform.developer.request.CipCaterTakeoutOrderRefundAcceptRequest;
import com.sankuai.sjst.platform.developer.request.CipCaterTakeoutOrderRefundRejectRequest;
import com.sankuai.sjst.platform.developer.request.CipCaterTakeoutPoiCloseRequest;
import com.sankuai.sjst.platform.developer.request.CipCaterTakeoutPoiInfoQueryRequest;
import com.sankuai.sjst.platform.developer.request.CipCaterTakeoutPoiOpenRequest;
import com.superhelper.app.common.Consts;
import com.superhelper.app.domain.AccessToken;
import com.superhelper.app.mapper.AdminMapper;
import com.superhelper.app.utils.CipCaterQueryReviewRequest;
import com.superhelper.common.domain.AuserShop;
import com.superhelper.common.domain.TakeOutOrderStatus;
import com.superhelper.common.domain.TakeOutShopInfo;
import com.superhelper.common.service.RedisService;
import com.superhelper.common.utils.JsonHelper;

@Service
public class MtService {
    protected Logger log = LoggerFactory.getLogger(this.getClass());
    @Value("${mt.url}")
    private String url;
    @Value("${mt.developerId}")
    private String developerId;
    @Value("${mt.signKey}")
    private String signKey;
    @Value("${mt.callback_url}")
    private String callbackUrl;
    @Value("${mt.businessId}")
    private int businessId;
    @Autowired
    private RedisService redisService;
    @Autowired
    private AdminMapper adminMapper;
    private ThreadPoolExecutor threadPool = new ThreadPoolExecutor(5, 200, 1L, TimeUnit.SECONDS,
            new LinkedBlockingQueue<Runnable>());

    public String getAuthUrl(Integer auserId, String ePoiId) throws UnsupportedEncodingException {
        StringBuffer sb = new StringBuffer();
        sb.append(url);
        sb.append("?");
        sb.append("developerId=" + developerId);
        sb.append("&");
        sb.append("businessId=" + businessId);
        sb.append("&");
        sb.append("ePoiId=" + ePoiId);
        sb.append("&");
        sb.append("signKey=" + signKey);
        sb.append("&");
        String tmp = callbackUrl + "?auserId=" + auserId;
        sb.append("callbackUrl=" + URLEncoder.encode(tmp, "utf-8"));
        return sb.toString();
    }

    public TakeOutShopInfo getShopInfo(String shopId) throws Exception {
        CipCaterTakeoutPoiInfoQueryRequest request = new CipCaterTakeoutPoiInfoQueryRequest();
        request.setEPoiIds(shopId);
        request.setRequestSysParams(getSysParams(shopId));
        String body = request.doRequest();
        log.info("[mt->getShop]response,{},{}", request.getUrl(), body);
        Map<String, Object> map = JsonHelper.fromJson(body, Map.class);
        Object data = map.get("data");
        if (data != null) {
            String json = JsonHelper.toJson(data);
            List<TakeOutShopInfo> list = JsonHelper.fromJson(json, new TypeReference<List<TakeOutShopInfo>>() {
            });
            TakeOutShopInfo entity = list.get(0);
            BigDecimal divisor = new BigDecimal(1000000);
            BigDecimal lat = new BigDecimal(entity.getLatitude());
            BigDecimal lon = new BigDecimal(entity.getLongitude());
            lat = lat.divide(divisor, 6, BigDecimal.ROUND_HALF_EVEN);
            lon = lon.divide(divisor, 6, BigDecimal.ROUND_HALF_EVEN);
            entity.setLatitude(lat.doubleValue());
            entity.setLongitude(lon.doubleValue());
            entity.setShop_type(AuserShop.SHOP_MEITUAN);
            return entity;
        }
        return null;
    }

    private RequestSysParams getSysParams(String shopId) {
        RequestSysParams sysParams = new RequestSysParams();
        String appAuthToken = this.getToken(shopId);
        sysParams.setAppAuthToken(appAuthToken);
        sysParams.setCharset("utf-8");
        sysParams.setSecret(signKey);
        return sysParams;
    }

    public String getToken(String shopId) {

        // 后期优化，放缓存token
        String token_key = Consts.Cache.MT_TOKEN + shopId;
        AccessToken accessToken = redisService.get(token_key, AccessToken.class);
        if (accessToken != null) {
            return accessToken.getToken();
        } else {
            AuserShop s = adminMapper.getAuserShopByType(shopId, AuserShop.SHOP_MEITUAN);
            accessToken = JsonHelper.fromJson(s.getToken(), AccessToken.class);
            redisService.set(token_key, accessToken);
            return accessToken.getToken();
        }
    }

    public boolean confirmOrder(final String shopId, final String orderId) throws Exception {
        threadPool.submit(new Runnable() {
            @Override
            public void run() {
                // TODO Auto-generated method stub
                CipCaterTakeoutOrderConfirmRequest request = new CipCaterTakeoutOrderConfirmRequest();
                request.setRequestSysParams(getSysParams(shopId));
                request.setOrderId(Long.parseLong(orderId));
                try {
                    long time = System.currentTimeMillis();
                    String body = request.doRequest();
                    long t = System.currentTimeMillis() - time;
                    log.info("[mt->confirmOrder]response,{},cost:{},{}", request.getUrl(), t, body);
                    Map<String, Object> map = JsonHelper.fromJson(body, Map.class);
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    log.error("{}", e);
                }

            }
        });

        return true;

    }

    public boolean cancelOrder(String shopId, String orderId) throws Exception {
        CipCaterTakeoutOrderCancelRequest request = new CipCaterTakeoutOrderCancelRequest();

        request.setRequestSysParams(getSysParams(shopId));
        request.setOrderId(Long.parseLong(orderId));
        request.setReason("其他原因");
        request.setReasonCode("2007");
        String body = request.doRequest();
        log.info("[mt->cancelOrder]response,{},{}", request.getUrl(), body);
        Map<String, Object> map = JsonHelper.fromJson(body, Map.class);
        Object data = map.get("data");
        if (data != null && "ok".equalsIgnoreCase(data.toString())) { // 错误了
            return true;
        }
        return false;

    }

    public boolean agreeRefund(String shopId, String orderId) throws Exception {

        CipCaterTakeoutOrderRefundAcceptRequest request = new CipCaterTakeoutOrderRefundAcceptRequest();

        request.setRequestSysParams(getSysParams(shopId));
        request.setOrderId(Long.parseLong(orderId));
        request.setReason("同意退款");
        String body = request.doRequest();
        log.info("[mt->cancelOrder]response,{},{}", request.getUrl(), body);
        Map<String, Object> map = JsonHelper.fromJson(body, Map.class);
        Object data = map.get("data");
        if (data != null && "ok".equalsIgnoreCase(data.toString())) { // 错误了
            return true;
        }
        return false;
    }

    public boolean disagreeRefund(String shopId, String orderId) throws Exception {
        CipCaterTakeoutOrderRefundRejectRequest request = new CipCaterTakeoutOrderRefundRejectRequest();

        request.setRequestSysParams(getSysParams(shopId));
        request.setOrderId(Long.parseLong(orderId));
        request.setReason("拒绝退款");
        String body = request.doRequest();
        log.info("[mt->cancelOrder]response,{},{}", request.getUrl(), body);
        Map<String, Object> map = JsonHelper.fromJson(body, Map.class);
        Object data = map.get("data");
        if (data != null && "ok".equalsIgnoreCase(data.toString())) { // 错误了
            return true;
        }
        return false;
    }

    public boolean mtOpen(String shopId, Integer state) throws IOException, URISyntaxException {
        String body = null;
        if (state == 1) {
            CipCaterTakeoutPoiOpenRequest requestOpen = new CipCaterTakeoutPoiOpenRequest();
            requestOpen.setRequestSysParams(getSysParams(shopId));
            body = requestOpen.doRequest();
            log.info("[mt->mtOpen]response,{},{}", requestOpen.getUrl(), body);
        } else {
            CipCaterTakeoutPoiCloseRequest requestcolse = new CipCaterTakeoutPoiCloseRequest();
            requestcolse.setRequestSysParams(getSysParams(shopId));
            body = requestcolse.doRequest();
            log.info("[mt->mtOpen]response,{},{}", requestcolse.getUrl(), body);
        }

        Map<String, Object> map = JsonHelper.fromJson(body, Map.class);
        Object data = map.get("data");
        if (data != null && "ok".equalsIgnoreCase(data.toString())) { // 错误了
            return true;
        }
        return false;
    }

    public String getOrderStatus(String shopId, String orderId) throws IOException, URISyntaxException {
        CipCaterTakeoutOrderQueryByIdRequest request = new CipCaterTakeoutOrderQueryByIdRequest();
        request.setRequestSysParams(getSysParams(shopId));
        request.setOrderId(Long.parseLong(orderId));
        String body = request.doRequest();
        log.info("[mt->getOrderStatus]response,{},{}", request.getUrl(), body);
        Map<String, Object> map = JsonHelper.fromJson(body, Map.class);
        if (map.containsKey("data")) {
            Map<String, Object> map1 = (Map) map.get("data");
            Object status = map1.get("status");
            if (status != null) {
                if (Long.valueOf(status + "").equals(9)) {
                    return TakeOutOrderStatus.INVALID.getValue();
                } else if (Long.valueOf(status + "").equals(8)) {
                    return TakeOutOrderStatus.SETTLED.getValue();
                }
            }
        }
        return null;
    }

    public boolean queryReview(String shopId) throws Exception {
        CipCaterQueryReviewRequest request = new CipCaterQueryReviewRequest();
        request.setRequestSysParams(getSysParams(shopId));
        request.setePoiId(shopId);
        Calendar c = Calendar.getInstance();
        c.set(Calendar.DAY_OF_MONTH, c.get(Calendar.DAY_OF_MONTH) - 30);
        Long startTime = c.getTimeInMillis();
        Long endTime = System.currentTimeMillis();
        request.setEndTime(endTime);
        request.setStartTime(startTime);
        request.setOffset(0);
        request.setOffset(20);
        String body = request.doRequest();
        log.info("[mt->queryReview]response,{},{}", request.getUrl(), body);
        Map<String, Object> map = JsonHelper.fromJson(body, Map.class);
        Object data = map.get("data");
        if (data != null && "ok".equalsIgnoreCase(data.toString())) { // 错误了
            return true;
        }
        return false;

    }
}
